package com.example.activiti.controller;

import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipInputStream;

/**
 * @Description :
 * @Author : Bruce Lee
 * @CreateTime : 2024/5/16
 */

@RestController
@Slf4j
public class TestController {

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    HistoryService historyService;

    /**
     * 测试springsecurity是否关闭
     */
    @RequestMapping("/test")
    public void test() {
        log.info("test");
    }

    /**
     * 部署流程
     *
     * @param file
     */
    @PostMapping("/deploy")
    public void deploy(@RequestPart("file") MultipartFile file, @RequestParam("processName") String processName) {
        try {
            if (file.isEmpty()) {
                throw new NullPointerException("部署压缩包不能为空");
            }
            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
            //压缩流
            ZipInputStream zip = new ZipInputStream(file.getInputStream());
            deploymentBuilder.addZipInputStream(zip);
            //设置部署流程名称
            deploymentBuilder.name(processName);
            deploymentBuilder.key(processName);
            //部署流程（对应act_re_deployment表）
            Deployment deploy = deploymentBuilder.deploy();
            log.info("部署成功，部署ID：{}", deploy.getId());

            // 获取流程定义ID 一般系统只会存在一个流程定义
            repositoryService.createProcessDefinitionQuery().list().forEach(item -> {
                if (processName.equals(item.getKey())){
                    log.info("流程定义ID：{}", item.getId());
                }
            });



            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().list().get(0);
            log.info("流程定义ID：{}", processDefinition.getId());
//            return ReturnData.buildSuccess(deploy);

        } catch (Exception e) {
            log.error("部署失败：" + e.toString());
//            return ReturnData.buildError(e.toString());
        }
    }

    @GetMapping("queryDeploymentInfo")
    public void queryDeploymentInfo() {
        //也可以设置查询部署筛选条件，自行查询API，基本上都是见名知意的
        List<Deployment> list = repositoryService.createDeploymentQuery().list();
        log.info("流程部署信息：{}", list);
        log.info("流程部署信息：{}", list.toString());
//        return ReturnData.buildSuccess(list.toString());
    }

    @PostMapping("startProcess")
    public void startProcess(String processDefinitionId) {
        log.info("发起流程，processDefinitionId：{}", processDefinitionId);
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).list();
        if (list.size() != 1) {
            log.error("流程定义不存在");
            return;
//            return ReturnData.buildError("流程定义不存在");
        }
        //通过流程定义ID启动一个流程实例
        // 传递相关参数
        HashMap<String, Object> map = new HashMap<>();
        map.put("manager", "张三");
        map.put("personnel", "李四");

        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, map);
        log.info("流程实例：{}", processInstance);
        log.info("发起成功");
        return;
//        return ReturnData.buildSuccess("发起成功");
    }

    @PostMapping("completeTask")
    public void completeTask(String processInstanceId) {
        //根据流程实例id，查询任务
        List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        if (taskList.size() != 1) {
            log.error("当前没有任务");
            return;
//            return ReturnData.buildError("当前没有任务");
        }
        log.info("任务列表：{}", taskList);
        //根据任务id，完成任务
        taskService.complete(taskList.get(0).getId());
        log.info("完成任务");
        return;
//        return ReturnData.buildSuccess("完成任务");
    }

    @GetMapping("queryHistoryProcessInstance")
    public void queryHistoryProcessInstance() {
        //也可以设置查询条件，自行查询API
//        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().list();
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().list();
        log.info("查询历史流程实例 {}", list);
        log.info("查询历史流程实例 {}", list.toString());
//        return ReturnData.buildSuccess(list.toString());
    }

    @GetMapping("queryByAssigneeTask")
    public void queryByAssigneeTask() {
        List<Task> taskList = taskService.createTaskQuery()
                //代办人姓名(不一定是登录用户名，可以用用户ID替换)
                .taskAssignee("李四")
                //活动状态
//                .active()
                .list();
        log.info("根据代办人查询任务 {}", taskList);
//        return ReturnData.buildSuccess(taskList.toString());
    }
}
